package com.adulcimer.services;

import com.adulcimer.models.dto.WordTagDto;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.UUID;

/**
 * @Classname Simon
 * @Description
 * @Date 2025/3/11 14:24
 * @Created by Simon
 */
@Service
public class PoiService {

    // 占位符格式：${category.type.field}，例如 ${table.string.name}
    private static final Pattern TAG_PATTERN = Pattern.compile("\\$\\{(\\w+)\\.(\\w+)\\.(\\w+)}");

    /**
     * 从文档中解析所有占位符标签（包括段落和表格），为每个标签生成唯一 id
     * @param templateStream 模板文件输入流
     * @return 标签列表
     */
    public List<WordTagDto> parseTemplate(InputStream templateStream) throws Exception {
        List<WordTagDto> tags = new ArrayList<>();
        XWPFDocument document = new XWPFDocument(templateStream);

        // 解析段落
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            tags.addAll(parseText(paragraph.getText()));
        }

        // 解析所有表格
        for (XWPFTable table : document.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    // 可能单元格中有多个段落
                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
                        tags.addAll(parseText(paragraph.getText()));
                    }
                }
            }
        }

        // 解析页眉
        for (XWPFHeader header : document.getHeaderList()) {
            for (XWPFParagraph paragraph : header.getParagraphs()) {
                tags.addAll(parseText(paragraph.getText()));
            }
            for (XWPFTable table : header.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        for (XWPFParagraph paragraph : cell.getParagraphs()) {
                            tags.addAll(parseText(paragraph.getText()));
                        }
                    }
                }
            }
        }

        // 解析页脚
        for (XWPFFooter footer : document.getFooterList()) {
            for (XWPFParagraph paragraph : footer.getParagraphs()) {
                tags.addAll(parseText(paragraph.getText()));
            }
            for (XWPFTable table : footer.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        for (XWPFParagraph paragraph : cell.getParagraphs()) {
                            tags.addAll(parseText(paragraph.getText()));
                        }
                    }
                }
            }
        }

        document.close();
        return tags;
    }

    /**
     * 辅助方法：解析传入的文本，返回符合格式的标签集合
     */
    private List<WordTagDto> parseText(String text) {
        List<WordTagDto> tagList = new ArrayList<>();
        Matcher matcher = TAG_PATTERN.matcher(text);
        while (matcher.find()) {
            String category = matcher.group(1);
            String type = matcher.group(2);
            String field = matcher.group(3);
            // 生成唯一 id
            String id = UUID.randomUUID().toString();
            WordTagDto tag = new WordTagDto(category, type, field, id);
            tagList.add(tag);
        }
        return tagList;
    }

    /**
     * 根据传入的数据填充模板，生成最终的文档
     * @param templateStream 原始模板流
     * @param dataMap  前端传入的数据，假设 key 为占位符全内容，如 "table.string.name"
     * @param outputStream 输出流保存生成的文档
     */
    public void fillTemplate(InputStream templateStream, Map<String, String> dataMap, OutputStream outputStream) throws Exception {
        XWPFDocument document = new XWPFDocument(templateStream);

        // 替换段落中的占位符
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            replaceInParagraph(paragraph, dataMap);
        }

        // 替换表格中各单元格的占位符
        for (XWPFTable table : document.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph paragraph : cell.getParagraphs()) {
                        replaceInParagraph(paragraph, dataMap);
                    }
                }
            }
        }

        document.write(outputStream);
        document.close();
    }

    /**
     * 辅助方法：在段落中查找并替换占位符
     */
    private void replaceInParagraph(XWPFParagraph paragraph, Map<String, String> dataMap) {
        String paragraphText = paragraph.getText();
        Matcher matcher = TAG_PATTERN.matcher(paragraphText);
        StringBuffer sb = new StringBuffer();
        boolean found = false;
        while (matcher.find()) {
            String key = matcher.group(1) + "." + matcher.group(2) + "." + matcher.group(3);
            // 根据 key 获取替换内容，如果没有则为空字符串
            String replacement = dataMap.getOrDefault(key, "");
            matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
            found = true;
        }
        matcher.appendTail(sb);
        if (found) {
            // 为了简单起见，这里先清除所有 run，再添加一个新的 run，
            // 如果需要保留样式，则需要更复杂的逻辑
            List<XWPFRun> runs = paragraph.getRuns();
            for (int i = runs.size() - 1; i >= 0; i--) {
                paragraph.removeRun(i);
            }
            XWPFRun run = paragraph.createRun();
            run.setText(sb.toString(), 0);
        }
    }
}
